from rest_framework.viewsets import GenericViewSet
from rest_framework.response import Response
from rest_framework.request import Request
from rest_framework import status
from drf_spectacular.utils import extend_schema

from .serializers import ExecuteSerializer, RepositorySerializer, RepositoryMutationSerializer, TaskSerializer, TaskSummarySerializer
from .models import Repository, Task
from .runner import AnsibleRunner


class RepositoryViewSet(GenericViewSet):
    queryset = Repository.objects.all()
    serializer_class = RepositorySerializer

    @extend_schema("createRepository")
    def create(self, request: Request, *args, **kwargs):
        print(request.FILES)
        serializer = RepositorySerializer(data=request.data)
        if serializer.is_valid():
            serializer.save(created_by=request.user, updated_by=request.user)
            return Response(data=serializer.data)
        return Response(data=serializer.errors, status=status.HTTP_400_BAD_REQUEST)

    @extend_schema("listRepositories")
    def list(self, request: Request, *args, **kwargs):
        queryset = self.paginate_queryset(self.get_queryset())
        serializer = RepositorySerializer(instance=queryset, many=True)
        return self.get_paginated_response(serializer.data)

    @extend_schema("getRepository")
    def retrieve(self, request: Request, *args, **kwargs):
        obj = self.get_object()
        serializer = RepositorySerializer(instance=obj)
        return Response(data=serializer.data)

    @extend_schema("updateRepository", request=RepositoryMutationSerializer)
    def update(self, request: Request, *args, **kwargs):
        obj = self.get_object()
        serializer = RepositoryMutationSerializer(instance=obj, data=request.data)
        if serializer.is_valid():
            serializer.save(updated_by=request.user)
            return Response(data=serializer.data)
        return Response(data=serializer.errors, status=status.HTTP_400_BAD_REQUEST)


    @extend_schema("removeRepository")
    def destroy(self, request: Request, *args, **kwargs):
        obj = self.get_object()
        obj.delete()
        return Response(status=status.HTTP_204_NO_CONTENT)


class ExecuteViewSet(GenericViewSet):
    serializer_class = TaskSerializer
    queryset = Task.objects.all()

    @extend_schema("execute", request=ExecuteSerializer)
    def create(self, request: Request, *args, **kwargs):
        serializer = ExecuteSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save(created_by=request.user, updated_by=request.user)
            runner = AnsibleRunner(serializer.instance)
            runner.execute()
            return Response(data=TaskSerializer(instance=serializer.instance).data)
        return Response(data=serializer.errors, status=status.HTTP_400_BAD_REQUEST)

    @extend_schema("listTasks", responses=TaskSummarySerializer(many=True))
    def list(self, request: Request, *args, **kwargs):
        queryset = self.paginate_queryset(self.get_queryset())
        serializer = TaskSummarySerializer(instance=queryset, many=True)
        return self.get_paginated_response(serializer.data)

    @extend_schema("getTask")
    def retrieve(self, request: Request, *args, **kwargs):
        obj = self.get_object()
        serializer = TaskSerializer(instance=obj)
        return Response(data=serializer.data)
